package com.yanfan.common.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.yanfan.common.constant.CacheConstants;
import com.yanfan.common.core.redis.RedisCache;
import com.yanfan.common.core.text.Convert;
import com.yanfan.common.utils.file.FileUtils;
import com.yanfan.common.utils.spring.SpringUtils;

import java.io.File;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

public class AuthOsValidUtil {

    /**
     * 授权码
     * 授权码 = aes加密(机器码+时间)
     */
    private String authorizeCode;

    private final String KEY = SpringUtils.getRequiredProperty("yanfan.private-key");
    private final String PROJECT_PATH = SpringUtils.getRequiredProperty("yanfan.project-path");
    private final RedisCache redisCache = SpringUtil.getBean("redisCache", RedisCache.class);
    private static final String OS_NUMBER = OSUtils.getOSNumber();

    public void verification() {
        try {
            String path = PROJECT_PATH + File.separator + "OSNUM.txt";
            if (!FileUtil.exist(path)) {
                FileUtil.writeBytes(OS_NUMBER.getBytes(), path);
            }
            authorizeCode = Convert.toStr(redisCache.getCacheObject(CacheConstants.SYS_CONFIG_KEY + "sys.authorizeCode"));
            if (DateUtil.compare(DateUtils.parseDate(parseTime(), DateUtils.YYYY_MM_DD_HH_MM_SS), DateUtils.getNowDate()) < 0) {
                // 删除程序
                // FileUtils.forceDelete(FileUtils.getFile("/yanfan-admin"));
                System.exit(1);
            }
        } catch (Exception e) {
            System.exit(1);
        }
    }

    private String parseTime() throws Exception {
        String string = RSAUtils.decryptWithPublicKey(authorizeCode, RSAUtils.getPublicKey(KEY));
        // 获取机器码
        if (!string.startsWith(OS_NUMBER)) {
            throw new RuntimeException("校验失败");
        }
        return StringUtils.substring(string, OS_NUMBER.length());
    }

    /**
     * 不要把main打包进去，防止被反编译，也不要写中文提示！！！！
     * 授权码生成方法
     * 注意：需要将生成好的私钥保存好，不要提供给任何客户
     * 私钥：服务端加密数据时使用
     * 公钥：客户解密数据使用
     */
    public static void main(String[] args) throws Exception {

        // 1. 生成密钥对
        KeyPair keyPair = RSAUtils.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 2. 获取密钥字符串（模拟存储/传输）
        String publicKeyStr = RSAUtils.getPublicKeyString(publicKey);
        String privateKeyStr = RSAUtils.getPrivateKeyString(privateKey);
        // 公钥:
        // publicKeyStr = "";
        System.out.println("publicKeyStr: " + publicKeyStr);
        // 私钥: 不要将自己的私钥放到这里！！！！！
        // privateKeyStr = "";
        System.out.println("privateKeyStr: " + privateKeyStr);
        // 私钥加密，私钥自己保留
        String data = RSAUtils.encryptWithPrivateKey(OS_NUMBER + "2099-12-31 23:59:59", RSAUtils.getPrivateKey(privateKeyStr));
//        String data = RSAUtils.encryptWithPrivateKey("038e-1ee5-ee15-4005-18ce-15b7-312d-78ee" + "2099-12-31 23:59:59", RSAUtils.getPrivateKey(privateKeyStr));
//        String data = RSAUtils.encryptWithPrivateKey(
//                "038e-1ee5-ee15-4005-18ce-15b7-312d-78ee" + "2025-06-25 23:59:59",
//                RSAUtils.getPrivateKey(privateKeyStr)
//        );
        System.out.println(data);
        // 公钥解密，公钥提供给客户
        System.out.println(RSAUtils.decryptWithPublicKey(data, RSAUtils.getPublicKey(publicKeyStr)));
    }
}
